﻿using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using championship_randomer.Models;
using System.IO;
using System;
using System.Collections.Generic;
using FluentAvalonia.UI.Controls;
using System.Linq;

namespace championship_randomer.ViewModels;

public partial class MainViewModel : ViewModelBase
{
    private Random _random = new Random();
    [ObservableProperty]
    private string _greeting = "Welcome to Avalonia!";

    [ObservableProperty]
    private int _combinationsCount = 11;

    [ObservableProperty]
    private ObservableCollection<Track> _tracks = JsonConvert.DeserializeObject<ObservableCollection<Track>>(File.ReadAllText("tracks.json"));

    [ObservableProperty]
    private ObservableCollection<Car> _cars = JsonConvert.DeserializeObject<ObservableCollection<Car>>(File.ReadAllText("cars.json"));

    [ObservableProperty]
    private ObservableCollection<string> _randomStyles = new ObservableCollection<string>
    {
        "禁止出现赛道和车辆的相同组合",
        "禁止出现重复赛道，但允许出现重复车辆",
        "禁止出现重复车辆，但允许出现重复赛道",
        "禁止出现任何重复车辆和重复赛道",
        "禁止出现重复地区",
        "禁止出现重复地区和重复车辆"
    };

    [ObservableProperty]
    private int _selectedRandomStyleIndex = 0;

    [RelayCommand]
    public void Generate() {
        Combinations.Clear();
        switch (SelectedRandomStyleIndex) {
            case 0:
                Random0();
                break;
            case 1:
                Random1();
                break;
            case 2:
                Random2();
                break;
            case 3:
                Random3();
                break;
            case 4:
                Random4();
                break;
            case 5:
                Random5();
                break;
        }
    }

    private void Random0() {
        // all combinations count should be Tracks.Count * Cars.Count
        // we random select unique _combinationsCount numbers from [0, Tracks.Count * Cars.Count]
        // and then we get track and car by index
        var allCombinationsCount = Tracks.Count * Cars.Count;
        if (allCombinationsCount < CombinationsCount) {
            var dialog = new ContentDialog()
            {
                Title = "错误",
                Content = "组合数大于所有赛道和车辆的组合数",
                PrimaryButtonText = "确定"
            };
            dialog.ShowAsync();
            return;
        }
        var selectedCombinations = new HashSet<int>();
        while (selectedCombinations.Count < CombinationsCount) {
            selectedCombinations.Add(_random.Next(allCombinationsCount));
        }
        foreach (var combinationIndex in selectedCombinations) {
            var trackIndex = combinationIndex / Cars.Count;
            var carIndex = combinationIndex % Cars.Count;
            Combinations.Add(new CombinationControlViewModel() { TrackName=Tracks[trackIndex].Region + " - " + Tracks[trackIndex].Name, TrackLength=Tracks[trackIndex].Length, CarInfo=Cars[carIndex].Class });
        }
    }

    private void Random1() {
        // all combinations count should be Tracks.Count * Cars.Count
        // we random select unique _combinationsCount numbers from [0, Tracks.Count]
        // and then we get track and car by index
        var selectedTracks = new HashSet<int>();
        if (Tracks.Count < CombinationsCount) {
            var dialog = new ContentDialog()
            {
                Title = "错误",
                Content = "组合数大于所有赛道的数量",
                PrimaryButtonText = "确定"
            };
            dialog.ShowAsync();
            return;
        }
        while (selectedTracks.Count < CombinationsCount) {
            selectedTracks.Add(_random.Next(Tracks.Count));
        }
        foreach (var trackIndex in selectedTracks) {
            var carIndex = _random.Next(Cars.Count);
            Combinations.Add(new CombinationControlViewModel() { TrackName=Tracks[trackIndex].Region + " - " + Tracks[trackIndex].Name, TrackLength=Tracks[trackIndex].Length, CarInfo=Cars[carIndex].Class });
        }
    }
    private void Random2() {
        // all combinations count should be Tracks.Count * Cars.Count
        // we random select unique _combinationsCount numbers from [0, Cars.Count]
        // and then we get track and car by index
        var selectedCars = new HashSet<int>();
        if (Cars.Count < CombinationsCount) {
            var dialog = new ContentDialog()
            {
                Title = "错误",
                Content = "组合数大于所有车辆的数量",
                PrimaryButtonText = "确定"
            };
            dialog.ShowAsync();
            return;
        }
        while (selectedCars.Count < CombinationsCount) {
            selectedCars.Add(_random.Next(Cars.Count));
        }
        foreach (var carIndex in selectedCars) {
            var trackIndex = _random.Next(Tracks.Count);
            Combinations.Add(new CombinationControlViewModel() { TrackName=Tracks[trackIndex].Region + " - " + Tracks[trackIndex].Name, TrackLength=Tracks[trackIndex].Length, CarInfo=Cars[carIndex].Class });
        }
    }
    private void Random3() {
        // all combinations count should be Tracks.Count * Cars.Count
        // we random select unique _combinationsCount numbers from [0, Cars.Count]
        // and then we get track and car by index
        var selectedTracks = new HashSet<int>();
        var selectedCars = new HashSet<int>();
        if (Tracks.Count < CombinationsCount || Cars.Count < CombinationsCount) {
            var dialog = new ContentDialog()
            {
                Title = "错误",
                Content = "组合数大于所有车辆和赛道的数量",
                PrimaryButtonText = "确定"
            };
            dialog.ShowAsync();
            return;
        }
        while (selectedTracks.Count < CombinationsCount) {
            selectedTracks.Add(_random.Next(Tracks.Count));
        }
        while (selectedCars.Count < CombinationsCount) {
            selectedCars.Add(_random.Next(Cars.Count));
        }

        var selectedTracksList = selectedTracks.ToList();
        var selectedCarsList = selectedCars.ToList();
        
        for (int i = 0; i < selectedCars.Count; i++) {
            var trackIndex = selectedTracksList.ElementAt(i);
            var carIndex = selectedCarsList.ElementAt(i);
            Combinations.Add(new CombinationControlViewModel() { TrackName=Tracks[trackIndex].Region + " - " + Tracks[trackIndex].Name, TrackLength=Tracks[trackIndex].Length, CarInfo=Cars[carIndex].Class });
        }
    }

    private void Random4() {
        // all combinations count should be Tracks.Count * Cars.Count
        // we random select unique _combinationsCount numbers from [0, Tracks.Count]
        // and then we get track and car by index
        var regions = Tracks.Select(x => x.Region).Distinct().ToList();
        var selectedRegions = new HashSet<string>();
        if (regions.Count < CombinationsCount) {
            var dialog = new ContentDialog()
            {
                Title = "错误",
                Content = "组合数大于所有地区的数量",
                PrimaryButtonText = "确定"
            };
            dialog.ShowAsync();
            return;
        }
        while (selectedRegions.Count < CombinationsCount) {
            selectedRegions.Add(regions[_random.Next(regions.Count)]);
        }
        foreach (var region in selectedRegions) {
            var trackIndex = Tracks.ToList().FindIndex(x => x.Region == region);
            var carIndex = _random.Next(Cars.Count);
            Combinations.Add(new CombinationControlViewModel() { TrackName=Tracks[trackIndex].Region + " - " + Tracks[trackIndex].Name, TrackLength=Tracks[trackIndex].Length, CarInfo=Cars[carIndex].Class });
        }
    }

    private void Random5() {
        // all combinations count should be Tracks.Count * Cars.Count
        // we random select unique _combinationsCount numbers from [0, Cars.Count]
        // and then we get track and car by index
        var regions = Tracks.Select(x => x.Region).Distinct().ToList();
        var selectedRegions = new HashSet<string>();
        var selectedCars = new HashSet<int>();
        if (regions.Count < CombinationsCount || Cars.Count < CombinationsCount) {
            var dialog = new ContentDialog()
            {
                Title = "错误",
                Content = "组合数大于所有车辆和地区的数量",
                PrimaryButtonText = "确定"
            };
            dialog.ShowAsync();
            return;
        }
        while (selectedRegions.Count < CombinationsCount) {
            selectedRegions.Add(regions[_random.Next(regions.Count)]);
        }
        while (selectedCars.Count < CombinationsCount) {
            selectedCars.Add(_random.Next(Cars.Count));
        }

        var selectedRegionsList = selectedRegions.ToList();
        var selectedCarsList = selectedCars.ToList();

        for (int i = 0; i < selectedCars.Count; i++) {
            var trackIndex = Tracks.ToList().FindIndex(x => x.Region == selectedRegionsList.ElementAt(i));
            var carIndex = selectedCarsList.ElementAt(i);
            Combinations.Add(new CombinationControlViewModel() { TrackName=Tracks[trackIndex].Region + " - " + Tracks[trackIndex].Name, TrackLength=Tracks[trackIndex].Length, CarInfo=Cars[carIndex].Class });
        }
    }

    [ObservableProperty]
    private ObservableCollection<CombinationControlViewModel> _combinations = new();
}
